from typing import Any, Dict, List, Literal, Optional, Union

from pydantic import BaseModel, Field, ConfigDict


# =============================
# 工具相关模型 (Tools)
# =============================

class Function(BaseModel):
    """
    表示一个可被模型调用的函数定义。
    """
    name: str = Field(
        ...,
        description="函数的名称，必须与实际函数匹配"
    )
    description: Optional[str] = Field(
        None,
        description="函数的详细描述，用于帮助模型理解其用途"
    )
    parameters: Dict[str, Any] = Field(
        default_factory=dict,
        description="函数参数的 JSON Schema 定义"
    )


class Tool(BaseModel):
    """
    表示一个工具，目前仅支持 function 类型。
    """
    type: Literal["function"] = Field(
        "function",
        description="工具类型，当前仅支持 'function'"
    )
    function: Function = Field(
        ...,
        description="具体的函数对象定义"
    )


# =============================
# 工具选择模型 (Tool Choice)
# =============================

class ToolChoiceFunction(BaseModel):
    """
    指定要调用的函数名称。
    """
    name: str = Field(
        ...,
        description="要强制调用的函数名称"
    )


class ToolChoice(BaseModel):
    """
    控制模型必须调用特定工具。
    """
    type: Literal["function"] = Field(
        "function",
        description="工具类型，固定为 'function'"
    )
    function: ToolChoiceFunction = Field(
        ...,
        description="指定要调用的函数"
    )


# =============================
# 音频输出配置 (Audio)
# =============================

class Audio(BaseModel):
    """
    音频生成参数配置。
    """
    format: Literal["wav", "mp3", "flac", "opus", "pcm16"] = Field(
        ...,
        description="生成音频的格式，支持 wav, mp3, flac, opus, pcm16"
    )
    voice: Literal["alloy", "ash", "ballad", "coral", "echo", "fable", "nova", "onyx", "sage", "shimmer"] = Field(
        ...,
        description="语音声音风格，如 nova（清晰）、onyx（沉稳）等"
    )


# =============================
# 响应格式配置 (Response Format)
# =============================

class JsonSchema(BaseModel):
    """
    结构化输出的 JSON Schema 定义。
    """
    name: str = Field(
        ...,
        description="该 JSON Schema 的名称"
    )
    schema: Dict[str, Any] = Field(
        ...,
        description="符合 JSON Schema 规范的对象结构"
    )
    strict: Optional[bool] = Field(
        None,
        description="是否严格遵循此 Schema，部分模型支持"
    )


class ResponseFormat(BaseModel):
    """
    控制模型输出的格式。
    """
    type: Literal["text", "json_object", "json_schema"] = Field(
        ...,
        description="期望的输出格式：文本、JSON 对象或结构化 Schema"
    )
    json_schema: Optional[JsonSchema] = Field(
        None,
        description="当 type 为 json_schema 时，提供具体的 Schema 定义"
    )


# =============================
# 流式响应选项 (Stream Options)
# =============================

class StreamOptions(BaseModel):
    """
    流式传输时的附加选项。
    """
    include_usage: Optional[bool] = Field(
        None,
        description="流式响应中是否包含 token 使用量信息"
    )


# =============================
# 网络搜索选项 (Web Search)
# =============================

class WebSearchOptions(BaseModel):
    """
    网络搜索功能的配置。
    """
    enabled: bool = Field(
        True,
        description="是否启用网络搜索来获取实时信息"
    )


# =============================
# 预测输出 (Prediction)
# =============================

class Prediction(BaseModel):
    """
    预测性输出配置，用于加速响应。
    """
    content: str = Field(
        ...,
        description="预期将生成的内容片段，用于提升响应速度"
    )
    model: str = Field(
        ...,
        description="用于生成预测内容的模型标识"
    )


# =============================
# 主请求模型：ChatCompletionRequest
# =============================

class ChatCompletionRequest(BaseModel):
    """
    OpenAI 风格的聊天补全请求模型，包含所有可能的参数及其中文说明。
    """
    model_config = ConfigDict(
        extra="allow",  # 允许未声明字段，便于未来扩展
        validate_default=True,
        populate_by_name=True
    )

    messages: List[Dict[str, Any]] = Field(
        default_factory=list,
        description="对话历史消息列表，每条消息包含 role 和 content 字段"
    )
    model: str = Field(
        default="gpt-4o",
        description="用于生成响应的大模型 ID，例如 gpt-4o、o3-mini 等"
    )

    frequency_penalty: Optional[float] = Field(
        default=0.0,
        ge=-2.0,
        le=2.0,
        description="频率惩罚值，正值减少重复词汇出现的概率"
    )
    presence_penalty: Optional[float] = Field(
        default=0.0,
        ge=-2.0,
        le=2.0,
        description="存在惩罚值，正值鼓励模型探索新话题"
    )
    temperature: Optional[float] = Field(
        default=1.0,
        ge=0.0,
        le=2.0,
        description="采样温度，值越高输出越随机，越低越确定"
    )
    top_p: Optional[float] = Field(
        default=1.0,
        ge=0.0,
        le=1.0,
        description="核采样参数，模型从累积概率 top_p 的 token 中采样"
    )
    max_completion_tokens: Optional[int] = Field(
        None,
        description="生成内容的最大 token 数限制（含推理过程）"
    )
    n: Optional[int] = Field(
        default=1,
        ge=1,
        description="为每个输入生成多少个独立结果（choices），n > 1 会增加费用"
    )
    seed: Optional[int] = Field(
        None,
        description="随机种子（Beta 功能），尽力保证相同输入输出一致"
    )
    stop: Optional[Union[str, List[str]]] = Field(
        None,
        description="最多 4 个停止序列，遇到这些内容时停止生成"
    )
    logprobs: Optional[bool] = Field(
        False,
        description="是否返回输出 token 的对数概率"
    )
    top_logprobs: Optional[int] = Field(
        None,
        ge=0,
        le=20,
        description="每个 token 返回最可能的 top_k 个候选及其 logprob"
    )

    # --- 已弃用字段 ---
    functions: Optional[List[Function]] = Field(
        None,
        description="【已弃用】请使用 tools。模型可调用的函数列表"
    )
    function_call: Optional[Union[Literal["none", "auto"], Dict[str, str]]] = Field(
        None,
        description="【已弃用】请使用 tool_choice。控制是否调用函数"
    )
    max_tokens: Optional[int] = Field(
        None,
        description="【已弃用】请使用 max_completion_tokens。最大生成 token 数"
    )
    user: Optional[str] = Field(
        None,
        description="【已弃用】请使用 safety_identifier 或 prompt_cache_key。终端用户标识"
    )

    # --- 工具相关 ---
    tools: Optional[List[Tool]] = Field(
        None,
        description="模型可调用的工具列表，如函数、插件等"
    )
    tool_choice: Optional[Union[Literal["none", "auto", "required"], ToolChoice]] = Field(
        None,
        description="控制工具调用行为：none（不调）、auto（自动）、required（必调）或指定具体工具"
    )
    parallel_tool_calls: Optional[bool] = Field(
        True,
        description="是否允许并行调用多个工具"
    )

    # --- 响应格式 ---
    response_format: Optional[ResponseFormat] = Field(
        None,
        description="期望的输出格式，如 JSON 模式或纯文本"
    )

    # --- 音频输出 ---
    audio: Optional[Audio] = Field(
        None,
        description="音频生成参数，需配合 modalities 使用"
    )

    # --- 输出模态 ---
    modalities: Optional[List[Literal["text", "audio"]]] = Field(
        None,
        description="期望的输出形式，如 ['text'] 或 ['text', 'audio']"
    )

    # --- 流式输出 ---
    stream: Optional[bool] = Field(
        False,
        description="是否以流式（SSE）方式逐段返回响应"
    )
    stream_options: Optional[StreamOptions] = Field(
        None,
        description="流式传输的附加选项，如是否包含 usage"
    )

    # --- 元数据 ---
    metadata: Optional[Dict[str, str]] = Field(
        None,
        max_length=16,
        description="最多 16 对键值对，用于存储额外上下文信息"
    )

    # --- 缓存与安全 ---
    prompt_cache_key: Optional[str] = Field(
        None,
        description="用于缓存优化的请求键，提高缓存命中率"
    )
    safety_identifier: Optional[str] = Field(
        None,
        description="用户安全标识（建议哈希），用于检测滥用行为"
    )
    service_tier: Optional[Literal["auto", "default", "flex", "priority"]] = Field(
        "auto",
        description="服务层级：auto（自动）、default（标准）、flex（灵活）、priority（优先）"
    )

    # --- 实验性功能 ---
    prediction: Optional[Prediction] = Field(
        None,
        description="预测输出配置，适用于内容高度可预知的场景"
    )

    # --- 推理与输出长度控制 ---
    reasoning_effort: Optional[Literal["minimal", "low", "medium", "high"]] = Field(
        "medium",
        description="推理努力程度，影响响应深度与速度"
    )
    verbosity: Optional[Literal["low", "medium", "high"]] = Field(
        "medium",
        description="输出详细程度：低（简洁）、中、高（详尽）"
    )

    # --- 网络搜索 ---
    web_search_options: Optional[WebSearchOptions] = Field(
        None,
        description="网络搜索工具的配置选项"
    )

    # --- logits 偏置 ---
    logit_bias: Optional[Dict[str, float]] = Field(
        None,
        description="调整特定 token 的生成倾向，格式为 token_id -> bias (-100 到 100)"
    )

    # --- 存储 ---
    store: Optional[bool] = Field(
        False,
        description="是否存储本次输出用于后续模型评估或蒸馏"
    )


from typing import Any, Dict, List, Literal, Mapping, Optional, Union
from pydantic import BaseModel, Field, SecretStr, ConfigDict


class BaseChatOpenAISchema(BaseModel):
    """
    OpenAI 大语言模型的聊天接口基础封装类。
    支持同步/异步调用、流式输出、自定义客户端、代理设置等高级功能。
    """

    temperature: Optional[float] = Field(
        default=None,
        ge=0.0,
        le=2.0,
        description="采样温度，值越高输出越随机，越低越确定"
    )
    model_kwargs: Dict[str, Any] = Field(
        default_factory=dict,
        description="传递给模型 create 调用的额外参数（非标准参数建议使用 extra_body）"
    )

    request_timeout: Union[float, tuple[float, float], Any, None] = Field(
        default=None,
        alias="timeout",
        description="请求超时时间，支持 float 或 httpx.Timeout 对象"
    )

    # ========================
    # 重试与生成控制
    # ========================
    max_retries: Optional[int] = Field(
        default=None,
        ge=0,
        description="请求失败时的最大重试次数"
    )
    # ========================
    # 输出控制
    # ========================
    streaming: bool = Field(
        default=False,
        description="是否启用流式输出（逐块返回响应）"
    )
    stream_usage: Optional[bool] = Field(
        default=None,
        description="流式输出中是否包含 usage 元数据（需 API 支持）"
    )
    max_tokens: Optional[int] = Field(
        default=None,
        description="生成内容的最大 token 数限制"
    )

    extra_body: Optional[Mapping[str, Any]] = Field(
        default=None,
        description="附加 JSON 参数，用于 OpenAI 兼容 API（如 vLLM、LM Studio）"
    )

    # ========================
    # 模型配置
    # ========================
    # 它不是模型的“数据字段”，而是类的配置元数据,控制 Pydantic 模型的 行为规则，比如是否允许未知字段、是否支持别名等
    model_config = ConfigDict(
        populate_by_name=True,  # 允许通过别名（如 model）赋值
        extra="allow",  # 允许未声明字段
        validate_default=True,  # 验证默认值
        arbitrary_types_allowed=True  # 允许 Any 类型
    )


class BaseEmbeddingSchema(BaseModel):
    embedding_ctx_length: Optional[int] = Field(
        default=None,
        description="单次请求的最大 token 数限制"
    )

    request_timeout: Union[float, tuple[float, float], Any, None] = Field(
        default=None,
        alias="timeout",
        description="请求超时时间，支持 float 或 httpx.Timeout 对象"
    )

    # ========================
    # 重试与生成控制
    # ========================
    max_retries: Optional[int] = Field(
        default=None,
        ge=0,
        description="请求失败时的最大重试次数"
    )

    model_kwargs: Dict[str, Any] = Field(
        default_factory=dict,
        description="传递给模型 调用的额外参数"
    )

    model_config = ConfigDict(
        populate_by_name=True,  # 允许通过别名（如 model）赋值
        extra="allow",  # 允许未声明字段
        validate_default=True,  # 验证默认值
        arbitrary_types_allowed=True  # 允许 Any 类型
    )
